/**
 * DSM - Distributed Search Manager
 * Developed by Milspec Research International Pty Ltd
 * $Author: gsingh $
 * $Revision: 1.4 $
 * $Date: 2005/10/05 02:03:33 $
 * (c)Copyright 2004
 * education.au limited
 * DEST
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * Neither the names education.au limited, DEST nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 * To the extent permitted by law, the copyright owners of this software and
 * its contributors:
 * (i) exclude all warranties in relation to the software; and
 * (ii) exclude liability for all losses, costs, expenses and damages arising
 * in any way from the use of the software whether arising from or in
 * relation to breach of contract, negligence or any other tort, in equity
 * or otherwise. If the software is in breach of a warranty which is
 * implied by law, the copyright owners and contributors liability is
 * limited to the replacement of the software.
 *
 * @author	gsingh
 */

package au.edu.educationau.opensource.dsm.worker;

import java.util.List;

import au.edu.educationau.opensource.dsm.DeusExMachina;
import au.edu.educationau.opensource.dsm.util.Flog;

import com.swabunga.spell.engine.SpellDictionary;
import com.swabunga.spell.event.SpellCheckEvent;
import com.swabunga.spell.event.SpellCheckListener;
import com.swabunga.spell.event.SpellChecker;
import com.swabunga.spell.event.StringWordTokenizer;

/**
 * Uses the Spell Check Service, in a threaded fashion. Currently, a SearchTask,
 * SpellCheckTask and ThesauriTask are unique classes. Perhaps they need to be
 * consolidated for debugging and control purposes? TBC 20/5/04
 */

public class SpellCheckTask extends java.lang.Object implements java.lang.Runnable, SpellCheckListener {
	private long token = 0;
	private long timeTaken = 0;
	private SpellChecker spellCheck;
	private String words = "";
	private boolean correctedTerms = false;
	private boolean finished = false;

	/**
	 * Builds a spell check task using the token, words that require spelling
	 * and a dictionary
	 * 
	 * @param token
	 * @param words
	 * @param dictionary
	 */
	public SpellCheckTask(long token, String words, SpellDictionary dictionary) {
		this.token = token;
		this.spellCheck = new SpellChecker(dictionary);
		this.spellCheck.addSpellCheckListener(this);
		this.words = words;
	}

	/**
	 * Returns a spelling error
	 * 
	 * @param event
	 */
	public void spellingError(SpellCheckEvent event) {
		List suggestions = event.getSuggestions();
		String invalidWord = event.getInvalidWord();
		if (suggestions.size() > 0) {
			words = words.replaceFirst(invalidWord, suggestions.get(0).toString());
			correctedTerms = true;
		}
	}

	/** Returns the time taken to check the spelling */
	public long getTimeTaken() {
		return timeTaken;
	}

	/** Terminate this task immediately */
	public void terminate() {
		// let it go. ;)
	}

	/** Checks if the spelling check task is complete */
	public boolean isFinished() {
		return finished;
	}

	/**
	 * Checks the spelling and if there are updated terms, updates the corrected
	 * terms field in the Search Result Set
	 */
	public void run() {
		long time1 = System.currentTimeMillis();
		if (null != words) {
			try {
				spellCheck.checkSpelling(new StringWordTokenizer(words));
				if (correctedTerms) {
					DeusExMachina._SearchResultService().updateCorrectedTerms(token, words);
				}
			} catch (Exception oe) {
				Flog.error(toString(), "Error while correcting the terms " + words, oe);
			}
		}
		finished = true;
		long time2 = System.currentTimeMillis();
		this.timeTaken = time2 - time1;
	}

	/** Class name display */
	public String toString() {
		return "o.m.d.w.SpellCheckTask";
	}

} // class SpellCheckTask

// -- EOF

